package com.halfsword.creativecraft.block.custom.machine.blockentity;

import com.halfsword.creativecraft.CreativeCraft;
import com.halfsword.creativecraft.block.custom.machine.blockentity.modules.*;
import com.halfsword.creativecraft.gui.machine.SteamCrusherMenu;
import com.halfsword.creativecraft.modules.BaseFluidTank;
import com.halfsword.creativecraft.modules.StagedSteamMechanism;
import com.halfsword.creativecraft.modules.interfaces.IDataSyncFacet;
import com.halfsword.creativecraft.modules.interfaces.IFluidHandlerFacet;
import com.halfsword.creativecraft.modules.interfaces.IPersistentDataModule;
import com.halfsword.creativecraft.recipe.SteamCrusherRecipe;
import com.halfsword.creativecraft.utils.ContainerDataBuilder;
import com.halfsword.creativecraft.utils.ContainerDataReader;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.FluidTags;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import static com.mojang.blaze3d.platform.GlDebug.isDebugEnabled;

public class SteamPowerCrusherBlockEntity extends BaseMachineBlockEntity {

    // 槽位定义
    public static final int[] FUEL_SLOTS = {0, 1};
    public static final int[] INPUT_SLOTS = {2, 3};
    public static final int OUTPUT_SLOT1 = 4;
    public static final int OUTPUT_SLOT2 = 5;
    private static final int SLOT_COUNT = 6;

    // 流体槽索引
    private static final int WATER_TANK_1 = 0;
    private static final int WATER_TANK_2 = 1;
    public static final int MAX_WATER_TANK_CAPACITY = 16000;

    // 蒸汽机制参数
    public static final double MAX_TORQUE = 100.0;
    private static final double RISING_RATE = 1.0;
    private static final double DECLINING_RATE = 5.0;
    private static final int WATER_CONSUMPTION = 50;  // mB/tick
    private static final int FUEL_CONSUMPTION = 100;   // 单位/tick
    private static final int MIN_WATER = 500;          // mB
    public static final int MIN_FUEL = 1000;          // 单位

    // 模块引用
    protected SteamCrusherRecipeHandlerModule recipeHandlerModule;
    protected SteamMechanismModule steamMechanismModule;
    protected CrusherFluidHandlerModule fluidHandlerModule;
    protected CrusherItemHandlerModule itemHandlerModule;

    public SteamPowerCrusherBlockEntity(BlockPos pos, BlockState state) {
        super(TileEntities.STEAM_POWER_CRUSHER_BE.get(), pos, state);
    }

    // ================= 模块初始化 =================
    @Override
    protected void initializeModules() {
        // 初始化物品处理模块
        itemHandlerModule = new CrusherItemHandlerModule(
                "steam_crusher_item_handler",
                SLOT_COUNT,
                FUEL_SLOTS,
                INPUT_SLOTS,
                new int[]{OUTPUT_SLOT1, OUTPUT_SLOT2}
        );
        registerModule(itemHandlerModule);

        // 初始化流体处理模块
        fluidHandlerModule = new CrusherFluidHandlerModule(
                "steam_crusher_fluid_handler",
                MAX_WATER_TANK_CAPACITY,
                this::isWater
        );
        registerModule(fluidHandlerModule);

        // 初始化蒸汽机制模块
        steamMechanismModule = new SteamMechanismModule(
                "steam_crusher_steam_mechanism",
                MAX_TORQUE, RISING_RATE, DECLINING_RATE,
                WATER_CONSUMPTION, FUEL_CONSUMPTION,
                MIN_WATER, MIN_FUEL
        );
        registerModule(steamMechanismModule);

        // 初始化配方处理模块
        recipeHandlerModule = new SteamCrusherRecipeHandlerModule(
                "steam_crusher_recipe_handler",
                itemHandlerModule,
                steamMechanismModule
        );
        registerModule(recipeHandlerModule);

        // 记录模块信息
        if (isDebugEnabled()) {
            CreativeCraft.LOGGER.debug("SteamPowerCrusher modules initialized: {}", getModuleInfo());
            CreativeCraft.LOGGER.debug("Total data fields: {}", getDataFieldCount());
        }
    }

    // ================= 抽象方法实现 =================
    @Override
    protected void updateCurrentRecipe() {
        recipeHandlerModule.updateCurrentRecipe();
    }

    @Override
    protected boolean hasActiveRecipe() {
        return recipeHandlerModule.hasActiveRecipe();
    }

    @Override
    protected void consumeInputs(int units) {
        recipeHandlerModule.consumeInputs(units);
    }

    @Override
    protected ItemStack getMainOutputProduct() {
        return recipeHandlerModule.getMainOutputProduct();
    }

    @Override
    protected ItemStack getByproductOutput() {
        return recipeHandlerModule.getByproductOutput();
    }

    @Override
    protected void onRecipeChanged() {
        recipeHandlerModule.onRecipeChanged();
    }

    // ================= 辅助方法 =================
    // 辅助方法：判断流体是否为水
    private boolean isWater(FluidStack fluid) {
        if (fluid == null || fluid.isEmpty()) {
            return false;
        }
        // 使用Forge的水标签
        return fluid.getFluid().is(FluidTags.WATER);
    }

    // ================= 能力系统 =================
    @NotNull
    @Override
    public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
        // 流体处理能力
        if (cap == ForgeCapabilities.FLUID_HANDLER) {
            return fluidHandlerModule.getFluidHandler().cast();
        }
        return super.getCapability(cap, side);
    }

    // ================= GUI 接口 =================
    @Override
    public Component getDisplayName() {
        return Component.translatable("block.creativecraft.steam_crusher");
    }

    @Nullable
    @Override
    public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) {
        return new SteamCrusherMenu(containerId, playerInventory, this, getContainerData());
    }

    // ================= 模块获取方法 =================
    public SteamCrusherRecipeHandlerModule getRecipeHandlerModule() {
        return recipeHandlerModule;
    }

    public SteamMechanismModule getSteamMechanismModule() {
        return steamMechanismModule;
    }

    public CrusherFluidHandlerModule getFluidHandlerModule() {
        return fluidHandlerModule;
    }

    public CrusherItemHandlerModule getItemHandlerModule() {
        return itemHandlerModule;
    }





    // ================= 蒸汽破碎机专用物品处理模块 =================
    public static class CrusherItemHandlerModule extends ItemHandlerModule {

        private final int[] fuelSlots;
        private final int[] inputSlots;
        private final int[] outputSlots;

        public CrusherItemHandlerModule(String moduleId, int slotCount, int[] fuelSlots, int[] inputSlots, int[] outputSlots) {
            super(moduleId, slotCount, inputSlots, outputSlots);
            this.fuelSlots = fuelSlots;
            this.inputSlots = inputSlots;
            this.outputSlots = outputSlots;
        }

        /**
         * 获取燃料槽位索引数组
         * @return 燃料槽位索引数组
         */
        public int[] getFuelSlots() {
            return fuelSlots;
        }

        /**
         * 计算总燃料量
         * @return 总燃料量
         */
        public int calculateTotalFuel() {
            int total = 0;
            for (int slot : fuelSlots) {
                ItemStack stack = getStackInSlot(slot);
                if (!stack.isEmpty()) {
                    total += ForgeHooks.getBurnTime(stack, null);
                }
            }
            return total;
        }

        /**
         * 消耗燃料
         * @param fuelNeeded 需要的燃料量
         * @return 实际消耗的燃料量
         */
        public int consumeFuel(int fuelNeeded) {
            int consumed = 0;

            for (int slot : fuelSlots) {
                if (fuelNeeded <= 0) break;

                ItemStack stack = getStackInSlot(slot);
                if (stack.isEmpty()) continue;

                int burnTime = ForgeHooks.getBurnTime(stack, null);
                if (burnTime > 0) {
                    int toConsume = Math.min(burnTime, fuelNeeded);
                    consumed += toConsume;
                    fuelNeeded -= toConsume;

                    // 消耗燃料物品
                    if (stack.getCount() == 1) {
                        ItemStack container = stack.getCraftingRemainingItem();
                        setStackInSlot(slot, container.isEmpty() ? ItemStack.EMPTY : container);
                    } else {
                        stack.shrink(1);
                    }
                }
            }

            return consumed;
        }
    }

    // ================= 蒸汽破碎机专用流体处理模块 =================
    public static class CrusherFluidHandlerModule implements IFluidHandlerFacet, IPersistentDataModule, IDataSyncFacet {

        private final String moduleId;
        private final BaseFluidTank[] fluidTanks;
        private final LazyOptional<IFluidHandler> fluidHandler;
        private boolean dataDirty = false;

        public CrusherFluidHandlerModule(String moduleId, int tankCapacity, java.util.function.Predicate<FluidStack> validator) {
            this.moduleId = moduleId;
            this.fluidTanks = new BaseFluidTank[]{
                    new BaseFluidTank("WaterTank1", tankCapacity, validator),
                    new BaseFluidTank("WaterTank2", tankCapacity, validator)
            };
            this.fluidHandler = LazyOptional.of(this::createFluidHandler);
        }

        @Override
        public String getModuleId() {
            return moduleId;
        }

        @Override
        public void tick(Level level, BlockPos pos, BlockState state) {
            // 流体处理模块的tick逻辑
        }

        @Override
        public void onUnload() {
            fluidHandler.invalidate();
        }

        @Override
        public BaseFluidTank[] getFluidTanks() {
            return fluidTanks;
        }

        @Override
        public LazyOptional<IFluidHandler> getFluidHandler() {
            return fluidHandler;
        }

        /**
         * 获取当前水量
         * @return 当前水量
         */
        public int getWaterLevel() {
            return fluidTanks[WATER_TANK_1].getFluidAmount() + fluidTanks[WATER_TANK_2].getFluidAmount();
        }

        /**
         * 提取水
         * @param amount 要提取的水量
         * @return 实际提取的水量
         */
        public int extractWater(int amount) {
            // 先尝试从第二个槽提取
            FluidStack drained = fluidTanks[WATER_TANK_2].drain(amount, IFluidHandler.FluidAction.EXECUTE);
            int extracted = drained.getAmount();

            // 如果不够，再从第一个槽提取
            if (extracted < amount) {
                FluidStack additionalDrained = fluidTanks[WATER_TANK_1].drain(amount - extracted, IFluidHandler.FluidAction.EXECUTE);
                extracted += additionalDrained.getAmount();
            }

            markDataDirty();
            return extracted;
        }

        protected IFluidHandler createFluidHandler() {
            return new IFluidHandler() {
                @Override
                public int getTanks() {
                    return fluidTanks.length;
                }

                @NotNull
                @Override
                public FluidStack getFluidInTank(int tank) {
                    if (tank < 0 || tank >= fluidTanks.length) {
                        return FluidStack.EMPTY;
                    }
                    return fluidTanks[tank].getFluid();
                }

                @Override
                public int getTankCapacity(int tank) {
                    if (tank < 0 || tank >= fluidTanks.length) {
                        return 0;
                    }
                    return fluidTanks[tank].getCapacity();
                }

                @Override
                public boolean isFluidValid(int tank, @NotNull FluidStack stack) {
                    if (tank < 0 || tank >= fluidTanks.length) {
                        return false;
                    }
                    return fluidTanks[tank].isFluidValid(stack);
                }

                @Override
                public int fill(FluidStack resource, FluidAction action) {
                    // 先尝试填充第一个槽
                    int filled = fluidTanks[WATER_TANK_1].fill(resource, action);
                    if (filled < resource.getAmount()) {
                        // 如果第一个槽没满，尝试填充第二个槽
                        FluidStack remaining = resource.copy();
                        remaining.setAmount(resource.getAmount() - filled);
                        filled += fluidTanks[WATER_TANK_2].fill(remaining, action);
                    }
                    if (action.execute() && filled > 0) {
                        markDataDirty();
                    }
                    return filled;
                }

                @NotNull
                @Override
                public FluidStack drain(FluidStack resource, FluidAction action) {
                    // 先尝试从第二个槽抽取
                    FluidStack drained = fluidTanks[WATER_TANK_2].drain(resource, action);

                    // 检查是否为空，避免操作空的FluidStack
                    if (drained.isEmpty() || drained.getAmount() < resource.getAmount()) {
                        // 如果第二个槽不够，尝试从第一个槽抽取
                        FluidStack remaining = resource.copy();
                        remaining.setAmount(resource.getAmount() - (drained.isEmpty() ? 0 : drained.getAmount()));
                        FluidStack additionalDrained = fluidTanks[WATER_TANK_1].drain(remaining, action);

                        // 正确处理空的情况
                        if (!additionalDrained.isEmpty()) {
                            if (drained.isEmpty()) {
                                drained = additionalDrained;
                            } else {
                                // 合并两个抽取结果
                                drained.setAmount(drained.getAmount() + additionalDrained.getAmount());
                            }
                        }
                    }

                    if (action.execute() && !drained.isEmpty()) {
                        markDataDirty();
                    }

                    return drained;
                }

                @NotNull
                @Override
                public FluidStack drain(int maxDrain, FluidAction action) {
                    // 先尝试从第二个槽抽取
                    FluidStack drained = fluidTanks[WATER_TANK_2].drain(maxDrain, action);

                    // 检查是否为空，避免操作空的FluidStack
                    if (drained.isEmpty() || drained.getAmount() < maxDrain) {
                        // 如果第二个槽不够，尝试从第一个槽抽取
                        int remaining = maxDrain - (drained.isEmpty() ? 0 : drained.getAmount());
                        FluidStack additionalDrained = fluidTanks[WATER_TANK_1].drain(remaining, action);

                        // 正确处理空的情况
                        if (!additionalDrained.isEmpty()) {
                            if (drained.isEmpty()) {
                                drained = additionalDrained;
                            } else {
                                // 合并两个抽取结果
                                drained.setAmount(drained.getAmount() + additionalDrained.getAmount());
                            }
                        }
                    }

                    if (action.execute() && !drained.isEmpty()) {
                        markDataDirty();
                    }

                    return drained;
                }
            };
        }

        // ================= 持久化接口实现 =================
        @Override
        public void saveToNBT(CompoundTag tag) {
            CompoundTag fluidTanksTag = new CompoundTag();
            for (int i = 0; i < fluidTanks.length; i++) {
                CompoundTag tankTag = new CompoundTag();
                fluidTanks[i].writeToNBT(tankTag);
                fluidTanksTag.put("Tank" + i, tankTag);
            }
            tag.put("FluidTanks", fluidTanksTag);
        }

        @Override
        public void loadFromNBT(CompoundTag tag) {
            if (tag.contains("FluidTanks")) {
                CompoundTag fluidTanksTag = tag.getCompound("FluidTanks");
                for (int i = 0; i < fluidTanks.length; i++) {
                    if (fluidTanksTag.contains("Tank" + i)) {
                        CompoundTag tankTag = fluidTanksTag.getCompound("Tank" + i);
                        fluidTanks[i].readFromNBT(tankTag);
                    }
                }
            }
        }

        @Override
        public String getDataKey() {
            return "steam_crusher_fluid_handler";
        }

        @Override
        public boolean isEmpty() {
            return getWaterLevel() == 0;
        }

        @Override
        public void reset() {
            for (BaseFluidTank tank : fluidTanks) {
                tank.setFluid(FluidStack.EMPTY);
            }
            markDataDirty();
        }

        // ================= 数据同步接口实现 =================
        @Override
        public void populateContainerData(ContainerDataBuilder builder) {
            builder.addReadOnlyField(() -> fluidTanks[WATER_TANK_1].getFluidAmount())
                    .addReadOnlyField(() -> fluidTanks[WATER_TANK_1].getCapacity())
                    .addReadOnlyField(() -> fluidTanks[WATER_TANK_2].getFluidAmount())
                    .addReadOnlyField(() -> fluidTanks[WATER_TANK_2].getCapacity());
        }

        @Override
        public void readFromContainerData(ContainerDataReader reader) {
            try {
                // 客户端数据读取
                int tank1Amount = reader.readInt();
                int tank1Capacity = reader.readInt();
                int tank2Amount = reader.readInt();
                int tank2Capacity = reader.readInt();

                // 更新客户端显示（如果需要）
                // 注意：流体数据在客户端通常是只读的，这里只是示例
            } catch (IndexOutOfBoundsException e) {
                CreativeCraft.LOGGER.error("Error reading fluid data: {}", e.getMessage());
            }
        }

        @Override
        public int getDataFieldCount() {
            return 4; // tank1Amount, tank1Capacity, tank2Amount, tank2Capacity
        }

        @Override
        public void markDataDirty() {
            dataDirty = true;
        }

        @Override
        public boolean isDataDirty() {
            return dataDirty;
        }

        @Override
        public void clearDataDirty() {
            dataDirty = false;
        }
    }

    // ================= 蒸汽破碎机专用配方处理模块 =================
    public static class SteamCrusherRecipeHandlerModule extends BaseRecipeHandlerModule
            implements IDataSyncFacet, IPersistentDataModule {

        private SteamCrusherRecipe currentRecipe;
        private ResourceLocation currentRecipeId;
        private int batchSize = 1;
        private boolean dataDirty = false;
        private final SteamMechanismModule steamMechanismModule;

        public SteamCrusherRecipeHandlerModule(String moduleId, CrusherItemHandlerModule itemHandler,
                                               SteamMechanismModule steamMechanismModule) {
            super(moduleId, itemHandler);
            this.steamMechanismModule = steamMechanismModule;
        }

        @Override
        public void updateCurrentRecipe() {
            if (getLevel() == null) return;

            SimpleContainer container = new SimpleContainer(
                    getItemHandler().getStackInSlot(INPUT_SLOTS[0]),
                    getItemHandler().getStackInSlot(INPUT_SLOTS[1])
            );
            Optional<SteamCrusherRecipe> recipe = getLevel().getRecipeManager()
                    .getRecipeFor(SteamCrusherRecipe.Type.INSTANCE, container, getLevel());

            if (recipe.isPresent()) {
                SteamCrusherRecipe newRecipe = recipe.get();
                if (currentRecipe == null || !currentRecipe.getId().equals(newRecipe.getId())) {
                    currentRecipe = newRecipe;
                    setMaxProgress(newRecipe.getProcessingTime());
                    setProgress(0);
                    batchSize = calculateBatchSize();
                    onRecipeChanged();
                }
            } else {
                currentRecipe = null;
                currentRecipeId = null;
                batchSize = 1;
            }
        }

        @Override
        public boolean hasActiveRecipe() {
            // 检查蒸汽状态
            StagedSteamMechanism.Stage stage = steamMechanismModule.getSteamMechanism().getCurrentStage();
            double torque = steamMechanismModule.getSteamMechanism().getCurrentTorque();
            boolean isSteamReady = (stage == StagedSteamMechanism.Stage.BALANCED && torque > MAX_TORQUE * 0.8);

            return isSteamReady && currentRecipe != null && hasInput() && hasOutputSpace();
        }

        @Override
        public void consumeInputs(int units) {
            if (currentRecipe == null || getLevel() == null) return;

            // 构建需求映射
            Map<Item, Integer> requiredCounts = new HashMap<>();
            for (Ingredient ingredient : currentRecipe.getIngredients()) {
                ItemStack[] matchingStacks = ingredient.getItems();
                if (matchingStacks.length > 0) {
                    Item item = matchingStacks[0].getItem();
                    int count = matchingStacks[0].getCount();
                    requiredCounts.merge(item, count, Integer::sum);
                }
            }

            // 按物品类型消耗
            for (Map.Entry<Item, Integer> entry : requiredCounts.entrySet()) {
                Item item = entry.getKey();
                int toConsume = entry.getValue() * units; // 乘以批次大小
                if (toConsume <= 0) continue;

                // 遍历所有输入槽消耗物品
                for (int slot : INPUT_SLOTS) {
                    if (toConsume <= 0) break;

                    ItemStack stack = getItemHandler().getStackInSlot(slot);
                    if (!stack.isEmpty() && stack.getItem() == item) {
                        int consumed = Math.min(stack.getCount(), toConsume);
                        stack.shrink(consumed);
                        toConsume -= consumed;
                    }
                }
            }

            markDataDirty();
        }

        @Override
        public ItemStack getMainOutputProduct() {
            return currentRecipe != null ? currentRecipe.getResultItem(null) : ItemStack.EMPTY;
        }

        @Override
        public ItemStack getByproductOutput() {
            return currentRecipe != null ? currentRecipe.getByproduct() : ItemStack.EMPTY;
        }

        @Override
        public void onRecipeChanged() {
            // 配方变化时的处理
            setProgress(0);
            batchSize = calculateBatchSize();
            markDataDirty();
        }

        @Override
        public int calculateBatchSize() {
            if (currentRecipe == null || getLevel() == null) return 1;

            int maxBatches = Integer.MAX_VALUE;

            // 统计所有输入槽中的物品
            Map<Item, Integer> availableCounts = new HashMap<>();
            for (int slot : INPUT_SLOTS) {
                ItemStack stack = getItemHandler().getStackInSlot(slot);
                if (!stack.isEmpty()) {
                    availableCounts.merge(stack.getItem(), stack.getCount(), Integer::sum);
                }
            }

            // 检查配方所需物品总量
            Map<Item, Integer> requiredCounts = new HashMap<>();
            for (Ingredient ingredient : currentRecipe.getIngredients()) {
                ItemStack[] matchingStacks = ingredient.getItems();
                if (matchingStacks.length > 0) {
                    Item item = matchingStacks[0].getItem();
                    int count = matchingStacks[0].getCount();
                    requiredCounts.merge(item, count, Integer::sum);
                }
            }

            // 按材料类型计算最大批次
            for (Map.Entry<Item, Integer> entry : requiredCounts.entrySet()) {
                Item item = entry.getKey();
                int required = entry.getValue();
                int available = availableCounts.getOrDefault(item, 0);

                if (available < required) {
                    return 0; // 材料不足
                }
                maxBatches = Math.min(maxBatches, available / required);
            }

            // 检查输出容量
            ItemStack output = getMainOutputProduct();
            if (output.isEmpty()) return 0;

            int outputLimit = getItemHandler().calculateOutputCapacity(output, OUTPUT_SLOT1);
            maxBatches = Math.min(maxBatches, outputLimit / output.getCount());

            // 检查副产品输出容量
            ItemStack byproduct = getByproductOutput();
            if (!byproduct.isEmpty()) {
                int byproductLimit = getItemHandler().calculateOutputCapacity(byproduct, OUTPUT_SLOT2);
                maxBatches = Math.min(maxBatches, byproductLimit / byproduct.getCount());
            }

            return Math.max(0, maxBatches);
        }

        @Override
        public Recipe<?> getCurrentRecipe() {
            return currentRecipe;
        }

        @Override
        public boolean hasInput() {
            return calculateBatchSize() > 0;
        }

        @Override
        public boolean hasOutputSpace() {
            ItemStack mainOutput = getMainOutputProduct();
            ItemStack byproduct = getByproductOutput();

            return getItemHandler().canInsertItem(mainOutput, OUTPUT_SLOT1) &&
                    (byproduct.isEmpty() || getItemHandler().canInsertItem(byproduct, OUTPUT_SLOT2));
        }

        // ================= 数据同步接口实现 =================
        @Override
        public void populateContainerData(ContainerDataBuilder builder) {
            builder.addReadOnlyField(this::getProgress)
                    .addReadOnlyField(this::getMaxProgress)
                    .addReadOnlyField(() -> currentRecipe != null ? 1 : 0)
                    .addReadOnlyField(this::calculateBatchSize);
        }

        @Override
        public void readFromContainerData(ContainerDataReader reader) {
            try {
                // 客户端数据读取
                int progress = reader.readInt();
                int maxProgress = reader.readInt();
                int hasRecipe = reader.readInt();
                int batchSize = reader.readInt();

                // 更新客户端显示
                setProgress(progress);
                setMaxProgress(maxProgress);
                // 注意：currentRecipe 和 batchSize 在客户端是只读的
            } catch (IndexOutOfBoundsException e) {
                CreativeCraft.LOGGER.error("Error reading recipe data: {}", e.getMessage());
            }
        }

        @Override
        public int getDataFieldCount() {
            return 4; // progress, maxProgress, hasRecipe, batchSize
        }

        @Override
        public void markDataDirty() {
            dataDirty = true;
        }

        @Override
        public boolean isDataDirty() {
            return dataDirty;
        }

        @Override
        public void clearDataDirty() {
            dataDirty = false;
        }

        // ================= 持久化接口实现 =================
        @Override
        public void saveToNBT(CompoundTag tag) {
            if (currentRecipe != null) {
                tag.putString("CurrentRecipe", currentRecipe.getId().toString());
            }
            tag.putInt("Progress", getProgress());
            tag.putInt("MaxProgress", getMaxProgress());
            tag.putInt("BatchSize", batchSize);
        }

        @Override
        public void loadFromNBT(CompoundTag tag) {
            if (tag.contains("CurrentRecipe")) {
                currentRecipeId = ResourceLocation.parse(tag.getString("CurrentRecipe"));
            }
            if (tag.contains("Progress")) {
                setProgress(tag.getInt("Progress"));
            }
            if (tag.contains("MaxProgress")) {
                setMaxProgress(tag.getInt("MaxProgress"));
            }
            if (tag.contains("BatchSize")) {
                batchSize = tag.getInt("BatchSize");
            }
        }

        @Override
        public String getDataKey() {
            return "steam_crusher_recipe_handler";
        }

        @Override
        public boolean isEmpty() {
            return currentRecipe == null && getProgress() == 0;
        }

        @Override
        public void reset() {
            currentRecipe = null;
            currentRecipeId = null;
            setProgress(0);
            setMaxProgress(200);
            batchSize = 1;
            markDataDirty();
        }

        @Override
        public void tick(Level level, BlockPos pos, BlockState state) {
            super.tick(level, pos, state);

            // 在tick中尝试加载配方
            if (currentRecipeId != null && currentRecipe == null && getLevel() != null) {
                getLevel().getRecipeManager().byKey(currentRecipeId).ifPresent(recipe -> {
                    if (recipe instanceof SteamCrusherRecipe) {
                        currentRecipe = (SteamCrusherRecipe) recipe;
                        currentRecipeId = null; // 清除ID，避免重复加载
                        markDataDirty();
                    }
                });
            }

            // 更新蒸汽机制的水位和燃料
            SteamPowerCrusherBlockEntity blockEntity = (SteamPowerCrusherBlockEntity) getBlockEntity();
            if (blockEntity == null) return;

            CrusherFluidHandlerModule fluidHandler = blockEntity.getFluidHandlerModule();
            CrusherItemHandlerModule itemHandler = blockEntity.getItemHandlerModule();

            if (fluidHandler != null) {
                steamMechanismModule.getSteamMechanism().setWaterLevel(fluidHandler.getWaterLevel());
            }

            if (itemHandler != null) {
                steamMechanismModule.getSteamMechanism().setFuelLevel(itemHandler.calculateTotalFuel());
            }

            // 在平衡状态时消耗燃料
            if (steamMechanismModule.getSteamMechanism().getCurrentStage() == StagedSteamMechanism.Stage.BALANCED) {
                int fuelConsumed = itemHandler.consumeFuel(steamMechanismModule.getSteamMechanism().getFuelConsumption());
                if (fuelConsumed > 0) {
                    markDataDirty();
                }
            }
        }

        /**
         * 获取方块实体
         * @return 方块实体
         */
        private SteamPowerCrusherBlockEntity getBlockEntity() {
            if (getLevel() == null) return null;
            return (SteamPowerCrusherBlockEntity) getLevel().getBlockEntity(getPos());
        }
    }
}